package com.zszq.ms.bigmodeltest.task;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zszq.ms.bigmodeltest.domain.response.Result;
import com.zszq.ms.bigmodeltest.entity.AiFinanceOrginalData;
import com.zszq.ms.bigmodeltest.entity.AiTask;
import com.zszq.ms.bigmodeltest.entity.AiTaskResult;
import com.zszq.ms.bigmodeltest.entity.AiTemplate;
import com.zszq.ms.bigmodeltest.enums.MainTaskStatusEnum;
import com.zszq.ms.bigmodeltest.enums.SubTaskStatusEnum;
import com.zszq.ms.bigmodeltest.mapper.AiBigmodelConfigMapper;
import com.zszq.ms.bigmodeltest.mapper.AiFinanceOrginalDataMapper;
import com.zszq.ms.bigmodeltest.mapper.AiTaskMapper;
import com.zszq.ms.bigmodeltest.mapper.AiTaskResultMapper;
import com.zszq.ms.bigmodeltest.model.BaseModel;
import com.zszq.ms.bigmodeltest.model.BaseModelFactory;
import com.zszq.ms.bigmodeltest.service.AiBigmodelConfigService;
import com.zszq.ms.bigmodeltest.service.AiTaskResultService;
import com.zszq.ms.bigmodeltest.service.AiTemplateService;
import com.zszq.ms.bigmodeltest.utils.AlyOSSUtil;
import com.zszq.ms.bigmodeltest.utils.FileParser;
import com.zszq.ms.bigmodeltest.vo.ValueScoreVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.InputStream;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 主任务处理类
 *
 * @author ms
 * @since 2025/03/28
 */
@Component
@Slf4j
public class TaskUtils {

    @Autowired
    private AiBigmodelConfigService aiBigmodelConfigService;

    @Autowired
    private BaseModelFactory baseModelFactory;

    @Autowired
    private AiTaskMapper aiTaskMapper;

    @Autowired
    private AiTaskResultMapper aiTaskResultMapper;

    @Autowired
    private AiFinanceOrginalDataMapper aiFinanceOrginalDataMapper;

    @Autowired
    private AiTemplateService aiTemplateService;

    @Autowired
    private AiBigmodelConfigMapper bigmodelConfigMapper;

    @Autowired
    private AiTaskResultService aiTaskResultService;

    /**
     * 执行任务
     *
     * @param aiTask 任务入参
     */
    public Result executeTask(AiTask aiTask) {
        aiTask.setStatusCode(MainTaskStatusEnum.RUNNING.getCode());
        aiTask.setStatusName(MainTaskStatusEnum.RUNNING.name());
        // 更新主任务状态为执行中
        aiTaskMapper.updateById(aiTask);
        List<AiTaskResult> aiTaskResults = aiTaskResultService.selectListByTaskId(aiTask.getId());
        if (aiTaskResults.size() > 0) {
            // 子任务处理
            for (AiTaskResult aiTaskResult : aiTaskResults) {
                subTaskHandle(aiTaskResult, aiTask, aiTaskResult.getBigModelConfigId());
            }
            // 更新主任务状态为执行完成
            aiTask.setStatusCode(MainTaskStatusEnum.END.getCode());
            aiTask.setStatusName(MainTaskStatusEnum.END.getValue());
            aiTaskMapper.updateById(aiTask);
            return Result.success("任务执行完完成");
        } else {
            // 更新主任务状态为执行完成
            aiTask.setStatusCode(MainTaskStatusEnum.END.getCode());
            aiTask.setStatusName(MainTaskStatusEnum.END.getValue());
            return Result.failure("请先添加子任务");
        }
    }

    public Result subTaskHandle(AiTaskResult aiTaskResult
            , AiTask aiTask, String modelCode) {
        try {
            // 获取每个关键字的最高评分对应的值(分页查询会导致结果有多条，根据评分高低取评分最高的为最终值)
            Map<String, ValueScoreVo> valueScoreVoMap = getStringValueScoreVoMap(aiTask, modelCode);
            AiFinanceOrginalData aiFinanceOrginalData = aiFinanceOrginalDataMapper.selectById(aiTask.getBasicDataId());
            BigDecimal finaScore = new BigDecimal(0);
            ValueScoreVo totalAsset = valueScoreVoMap.get("total_asset");
            if (totalAsset != null && totalAsset.getValue().equals(aiFinanceOrginalData.getTotalAsset())) {
                finaScore = finaScore.add(new BigDecimal(1));
            }
            ValueScoreVo prefitAsset = valueScoreVoMap.get("prefit_asset");
            if (prefitAsset != null && prefitAsset.getValue().equals(aiFinanceOrginalData.getPrefitAsset())) {
                finaScore = finaScore.add(new BigDecimal(1));
            }
            ValueScoreVo netAsset = valueScoreVoMap.get("net_asset");
            if (netAsset != null && netAsset.getValue().equals(aiFinanceOrginalData.getNetAsset())) {
                finaScore = finaScore.add(new BigDecimal(1));
            }
            ValueScoreVo dedutingNetAsset = valueScoreVoMap.get("deduting_net_asset");
            if (dedutingNetAsset != null && dedutingNetAsset.getValue().equals(aiFinanceOrginalData.getDedutingNetAsset())) {
                finaScore = finaScore.add(new BigDecimal(1));
            }
            // 设置和基线数据对比后的评分，todo 后续这部分评分逻辑要细化，这里只是简单模拟
            aiTaskResult.setScore(finaScore);
            aiTaskResult.setStatusCode(SubTaskStatusEnum.SUCCESS.getCode());
            aiTaskResult.setStatusName(SubTaskStatusEnum.SUCCESS.getValue());
            aiTaskResult.setContent(JSON.toJSONString(valueScoreVoMap));
            aiTaskResultMapper.updateById(aiTaskResult);
        } catch (Exception e) {
            aiTaskResult.setStatusCode(SubTaskStatusEnum.FAILED.getCode());
            aiTaskResult.setStatusName(SubTaskStatusEnum.FAILED.getValue());
            aiTaskResult.setFailInfo(e.getMessage());
            aiTaskResultMapper.updateById(aiTaskResult);
            return Result.failure("任务执行失败，原因请查看失败日志");
        }
        return Result.success();
    }

    private Map<String, ValueScoreVo> getStringValueScoreVoMap(AiTask aiTask, String modelCode) throws Exception {
        AiTemplate aiTemplate = aiTemplateService.getById(aiTask.getTemplateId());
        JSONObject attachmentInfoJson = JSON.parseObject(aiTask.getAttachmentInfo());
        String filePath = attachmentInfoJson.get("filePath").toString();
        String fileName = attachmentInfoJson.get("fileUrl").toString();
        InputStream inputStream = AlyOSSUtil.downloadFileStream(filePath);
        List<String> fileInfos = FileParser.parseFile(inputStream, fileName);
        Map<String, ValueScoreVo> valueScoreVoMap = new HashMap<>();
        for (String fileInfo : fileInfos) {
            String content =
                    "请从正文内容数据中提取以下关键字:" + aiTemplate.getKeyWords() + ",要求返回json格式,模板如下: " + aiTemplate.getContent() +
                            "，正文内容数据如下:" + fileInfo;
            BaseModel model = baseModelFactory.getModel(modelCode);
            JSONObject res = model.resTransferJson(content,
                    aiBigmodelConfigService.getConfigByCode(modelCode));
            Set<Map.Entry<String, Object>> entries = res.entrySet();
            for (Map.Entry<String, Object> entry : entries) {
                String key = entry.getKey();
                Object value = entry.getValue();
                JSONObject valueScore = (JSONObject) value;
                ValueScoreVo newValueScoreVo = valueScore.toJavaObject(ValueScoreVo.class);
                ValueScoreVo oldValueScoreVo = valueScoreVoMap.get(key);
                if (oldValueScoreVo == null) {
                    valueScoreVoMap.put(key, newValueScoreVo);
                } else {
                    if (oldValueScoreVo.getScore() < newValueScoreVo.getScore()) {
                        valueScoreVoMap.put(key, newValueScoreVo);
                    }
                }
            }
        }
        return valueScoreVoMap;
    }
}
